package com.hz.monitoring.module.hardware.service.monitoring_data;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.hz.monitoring.framework.common.pojo.PageResult;
import com.hz.monitoring.framework.tenant.core.context.TenantContextHolder;
import com.hz.monitoring.module.hardware.controller.admin.mcu_tenant_resource.vo.McuTenantResourceListReqVO;
import com.hz.monitoring.module.hardware.controller.admin.monitoring_data.vo.*;
import com.hz.monitoring.module.hardware.controller.admin.sensor_tenant_resource.vo.SensorTenantResourceListReqVO;
import com.hz.monitoring.module.hardware.controller.admin.sensor_tenant_resource.vo.SensorTenantResourceRespVO;
import com.hz.monitoring.module.hardware.controller.admin.vo.CustomFields;
import com.hz.monitoring.module.hardware.controller.admin.vo.CustomValueFields;
import com.hz.monitoring.module.hardware.convert.monitoring_data.MonitoringDataConvert;
import com.hz.monitoring.module.hardware.convert.sensor_tenant_resource.SensorTenantResourceConvert;
import com.hz.monitoring.module.hardware.dal.dataobject.mcu_tenant_resource.McuTenantResourceDO;
import com.hz.monitoring.module.hardware.dal.dataobject.monitoring_data.MonitoringDataDO;
import com.hz.monitoring.module.hardware.dal.dataobject.sensor_tenant_resource.SensorTenantResourceDO;
import com.hz.monitoring.module.hardware.dal.mysql.monitoring_data.MonitoringDataMapper;
import com.hz.monitoring.module.hardware.service.mcu_tenant_resource.McuTenantResourceService;
import com.hz.monitoring.module.hardware.service.sensor_tenant_resource.SensorTenantResourceService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.hz.monitoring.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.hz.monitoring.module.hardware.enums.ErrorCodeConstants.MONITORING_DATA_NOT_EXISTS;

/**
 * 监测数据 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class MonitoringDataServiceImpl implements MonitoringDataService {

    @Resource
    private MonitoringDataMapper monitoringDataMapper;

    @Resource
    private McuTenantResourceService mcuTenantResourceService;

    @Resource
    private SensorTenantResourceService sensorTenantResourceService;

    @Override
    public Long createMonitoringData(MonitoringDataCreateReqVO createReqVO) {
        // 插入
        MonitoringDataDO monitoringData = MonitoringDataConvert.convert(createReqVO);
        monitoringDataMapper.insert(monitoringData);
        // 返回
        return monitoringData.getId();
    }

    @Override
    public Boolean createBatchMonitoringData(List<MonitoringDataCreateReqVO> cmd) {
        List<MonitoringDataDO> monitoringDataDOList = cmd.stream().map(MonitoringDataConvert::convert).collect(Collectors.toList());
        monitoringDataMapper.insertBatch(monitoringDataDOList);
        return true;
    }

    @Override
    public void updateMonitoringData(MonitoringDataUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateMonitoringDataExists(updateReqVO.getId());
        // 更新
        MonitoringDataDO updateObj = MonitoringDataConvert.convert(updateReqVO);
        monitoringDataMapper.updateById(updateObj);
    }

    @Override
    public void deleteMonitoringData(Long id) {
        // 校验存在
        this.validateMonitoringDataExists(id);
        // 删除
        monitoringDataMapper.deleteById(id);
    }

    private void validateMonitoringDataExists(Long id) {
        if (monitoringDataMapper.selectById(id) == null) {
            throw exception(MONITORING_DATA_NOT_EXISTS);
        }
    }

    @Override
    public MonitoringDataDO getMonitoringData(Long id) {
        return monitoringDataMapper.selectById(id);
    }

    @Override
    public List<MonitoringDataDO> getMonitoringDataList(Collection<Long> ids) {
        return monitoringDataMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<MonitoringDataDO> getMonitoringDataPage(MonitoringDataPageReqVO pageReqVO) {
        return monitoringDataMapper.selectPage(pageReqVO);
    }

    @Override
    public List<MonitoringDataDO> getMonitoringDataList(MonitoringDataExportReqVO exportReqVO) {
        return monitoringDataMapper.selectList(exportReqVO);
    }

    @Override
    public List<MonitoringDataStatisticalRespVO> statisticalMonitoringData(MonitoringDataStatisticalReqVO cmd) {
        Long mcuTenantResourceId = null;
        Long tenantId = TenantContextHolder.getTenantId();
        List<MonitoringDataStatisticalRespVO> statisticalRespVOList = new ArrayList<>();

        //获取默认展示的MCU数据 第一个
        if (Objects.isNull(cmd.getMcuTenantResourceId())) {
            List<McuTenantResourceDO> mcuTenantResourceDOList = mcuTenantResourceService.getMcuTenantResourceList(McuTenantResourceListReqVO.builder().tenantId(tenantId).reverse(true).build());

            //不存在MCU时返回
            if (CollectionUtil.isEmpty(mcuTenantResourceDOList)) {
                return getNotEquipmentMonitoringDataStatisticalRespVOS(statisticalRespVOList, "暂无数据！请先关联设备");
            }
            mcuTenantResourceId = mcuTenantResourceDOList.get(0).getId();
        }
        List<SensorTenantResourceDO> sensorTenantResourceDOList = sensorTenantResourceService.getSensorTenantResourceList(SensorTenantResourceListReqVO.builder().mcuTenantResourceId(mcuTenantResourceId).tenantId(tenantId).build());


        //不存在传感器时返回
        if (CollectionUtil.isEmpty(sensorTenantResourceDOList)) {
            return getNotEquipmentMonitoringDataStatisticalRespVOS(statisticalRespVOList, "暂无数据！请先关联传感器");
        }


        //如果开始时间为空，只获取当年的数据
        Date beginCreateTime = cmd.getBeginCreateTime();
        if (Objects.isNull(beginCreateTime)) {
            beginCreateTime = DateUtil.beginOfYear(new Date()).toJdkDate();
        }

        List<MonitoringDataDO> monitoringDataDOList = monitoringDataMapper.selectList(MonitoringDataExportReqVO.builder().mcuTenantResourceId(mcuTenantResourceId).beginCreateTime(beginCreateTime).endCreateTime(cmd.getEndCreateTime()).build());
        List<MonitoringDataRespVO> monitoringDataRespVOList = MonitoringDataConvert.convertList(monitoringDataDOList);

        //组装统计数据
        Map<Long, MonitoringDataStatisticalRespVO> idByMonitoringDataStatisticalResp = new HashMap<>();
        List<SensorTenantResourceRespVO> sensorList = SensorTenantResourceConvert.convertList(sensorTenantResourceDOList);
        //组装最外层传感器
        Map<String, MonitoringDataStatisticalItemRespVO> idAndNameByDataItem = new HashMap<>();

        for (SensorTenantResourceRespVO sensor : sensorList) {
            List<MonitoringDataStatisticalItemRespVO> valueItem = new ArrayList<>();
            for (CustomFields customField : sensor.getValueMetadata()) {
                MonitoringDataStatisticalItemRespVO dataItem = MonitoringDataStatisticalItemRespVO.builder().dataAttributeName(customField.getName()).dataList(new ArrayList<>()).build();
                valueItem.add(dataItem);
                idAndNameByDataItem.put(sensor.getId() + "&and&" + customField.getName(), dataItem);
            }


            MonitoringDataStatisticalRespVO monitoringDataStatistical = MonitoringDataStatisticalRespVO.builder()
                    .sensorTenantResourceId(sensor.getId())
                    .sensorModel(sensor.getModel())
                    .sensorName(sensor.getModel() + "（" + sensor.getName() + "）" + "（" + sensor.getRemark() + "）")
                    .xAxis(new ArrayList<>())
                    .dataAttributes(valueItem)
                    .build();
            statisticalRespVOList.add(monitoringDataStatistical);
            idByMonitoringDataStatisticalResp.put(sensor.getId(), monitoringDataStatistical);
        }

        for (MonitoringDataRespVO monitoringData : monitoringDataRespVOList) {
            Long sensorId = monitoringData.getSensorTenantResourceId();
            MonitoringDataStatisticalRespVO monitoringDataStatistical = idByMonitoringDataStatisticalResp.get(sensorId);
            //存在此传感器，并且型号相同才能处理
            if (Objects.nonNull(monitoringDataStatistical) && monitoringDataStatistical.getSensorModel().equals(monitoringData.getSensorModel())) {
                //每个传感器的X轴
                monitoringDataStatistical.getXAxis().add(DateUtil.formatDateTime(monitoringData.getCreateTime()));

                //每个传感器多条数据线的值
                for (CustomValueFields valueMetadata : monitoringData.getValueMetadata()) {
                    MonitoringDataStatisticalItemRespVO dataItem = idAndNameByDataItem.get(sensorId + "&and&" + valueMetadata.getName());
                    if (Objects.nonNull(dataItem)) {
                        dataItem.getDataList().add(valueMetadata.getValue());
                    }
                }
            }
        }
        return statisticalRespVOList;
    }

    //设备
    private List<MonitoringDataStatisticalRespVO> getNotEquipmentMonitoringDataStatisticalRespVOS(List<MonitoringDataStatisticalRespVO> statisticalRespVOList, String sensorName) {
        MonitoringDataStatisticalItemRespVO dataItem = MonitoringDataStatisticalItemRespVO.builder().dataAttributeName("暂无数据").dataList(new ArrayList<>()).build();
        List<MonitoringDataStatisticalItemRespVO> dataAttributes = new ArrayList<>();
        dataAttributes.add(dataItem);
        MonitoringDataStatisticalRespVO statistical = MonitoringDataStatisticalRespVO.builder()
                .sensorName(sensorName)
                .xAxis(new ArrayList<>())
                .dataAttributes(dataAttributes)
                .build();
        statisticalRespVOList.add(statistical);
        return statisticalRespVOList;
    }

}
